package com.road.yishi.conn;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.road.common.core.NetConfig;
import com.road.common.core.NetConfigXml;
import com.road.common.core.ServerType;
import com.road.yishi.mina.LinkedClient;
import com.road.yishi.pb.cross.LoadMsgProto.LoadMsg;
import com.road.yishi.proto.MessageUtil;
import com.road.yishi.proto.PBMessage;
import com.road.yishi.protocol.Protocol;
import com.road.yishi.route.ServerRouteHandler;

/**
 * @Description :
 * @FileName: ClientSet.java
 * @Author :WeiHui.Zhang
 * @Data : 2016年2月26日 下午3:42:32
 * @Version:V1.00
 */
public class ClientSet {

	private static final Logger Log = LoggerFactory.getLogger(ConnMgr.class);
	
	private static LinkedClient self = null;

	private static List<LinkedClient> castleClients = Lists.newCopyOnWriteArrayList(); // Castle连接集合

	private static List<LinkedClient> chatClients = Lists.newCopyOnWriteArrayList(); // Chat连接集合

	private static List<LinkedClient> battleClients = Lists.newCopyOnWriteArrayList(); // Battle连接集合

	private static Map<String, List<LinkedClient>> crossClientMap = Maps.newConcurrentMap();

	private static List<String> crossKeyList = Lists.newArrayList();

	public static boolean init(int serverId) {

		initSelf(serverId);
		connect(ServerType.CASTLE, "castle");

		return true;
	}

	private static void connect(int serverType, String handName) {
		Collection<NetConfigXml> configXmls = NetConfig.getNetConfigXml(serverType);
		for (NetConfigXml netConfigXml : configXmls) {
			connect(serverType, netConfigXml, handName, 0);
		}

	}

	private static void connect(int serverType, NetConfigXml netConfigXml, String handName, int index) {
		if (netConfigXml == null) {
			Log.error("serverType : " + serverType + " , handName ：" + handName);
			return;
		}
		int serverId = netConfigXml.getId();
		String name = netConfigXml.getName();
		String address = netConfigXml.getAddress();
		int port = netConfigXml.getPort();

		ServerRouteHandler routeHandler = new ServerRouteHandler(handName);
		LinkedClient client = new LinkedClient(serverType, serverId, name, address, port, routeHandler, index);
		addLinkedClient(serverType, client);

		if (!client.connect()) { // 如果连接其他服务器不成功
			ClientTryer.getInstance().ctry(client, 10, -1);
		} else {//TODO 连接成功,发送网关信息到各个服务器
			sendRegisterMsg(serverType, client);
		}
	}

	private static void addLinkedClient(int serverType, LinkedClient client) {
		switch (serverType) {
		case ServerType.CASTLE:
			castleClients.add(client);
			break;
		case ServerType.CHAT:
			chatClients.add(client);
			break;
		case ServerType.BATTLE:
			battleClients.add(client);
			break;
		case ServerType.CROSS:
			String key = genKey(client);
			if (crossClientMap.containsKey(key)) {
				crossClientMap.get(key).add(client);
			} else {
				List<LinkedClient> clients = Lists.newArrayList();
				clients.add(client);
				crossClientMap.put(key, clients);
				crossKeyList.add(key);
			}
			break;

		default:
			break;
		}
	}
	
	public static void sendRegisterMsg(int serverType, LinkedClient client) {
		short code = 0;
		switch (serverType) {
		case ServerType.CASTLE:
			code = Protocol.C_REGISTER;
			break;
		case ServerType.BATTLE:
			code = Protocol.B_REGISTER;
			break;
		case ServerType.CHAT:
			code = Protocol.CH_REGISTER;
			break;
		case ServerType.CROSS:
			code = Protocol.CR_REGISTER;
		//	LoadMsg.Builder msg = client.writeProto();
		//	PBMessage packet = MessageUtil.buildMessage(Protocol.C_CROSS_ACTIVE, msg);
		//	routeCastle(packet);
			break;
		default:
			break;
		}
		if (code == 0) {
			return;
		}
		LoadMsg.Builder msg = self.writeProto();
		PBMessage pkg = MessageUtil.buildMessage(code, msg);
		client.send(pkg);

		// 连接上BattleServer,则通知CastleServer
		if (serverType == ServerType.BATTLE) {
			connectBattle();
		}
	}

	public static void connectBattle() {
		//BattleConnTryer.getInstance().tryConn();
	}
	
	private static String genKey(int id, String name, String address, int port) {
		return id + "_" + name + "_" + address + "_" + port;
	}

	private static String genKey(LinkedClient client) {
		return client.getId() + "_" + client.getName() + "_" + client.getAddress() + "_" + client.getPort();
	}

	private static void initSelf(int serverId) {
		NetConfigXml netConfigXml = NetConfig.getNetConfigXml(ServerType.GATEWAY, serverId);
		int id = netConfigXml.getId();
		String name = netConfigXml.getName();
		String address = netConfigXml.getAddress();
		int port = netConfigXml.getPort();
		self = new LinkedClient(ServerType.GATEWAY, id, name, address, port, null, 0);
	}

	public static void routeClient(PBMessage packet) {

	}

	/**
	 * 
	 * @Name: routeCastle
	 * @Description:转发到逻辑服
	 * @Author: WeiHui.Zhang
	 * @Version: V1.00
	 * @Date: 2016年2月26日下午4:36:11
	 * @param packet
	 * @Return: void
	 */
	public static void routeCastle(PBMessage packet) {
		LinkedClient client = castleClients.get(0);
		if (client == null) {
			Log.error("routeCastle client is null. code : " + Integer.toHexString(packet.getCode()) + ", userId : " + packet.getPlayerId());
		}
		route(client, packet);
	}

	private static void route(LinkedClient client, PBMessage packet) {
		if (client != null) {
			client.send(packet);
		}
	}

}
